package com.ajing.logextractor.extractor;

import com.ajing.logextractor.config.ExtractConfig;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONPath;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class JsonFlatExtractor extends AbstractExtractor {

    private final String patternSplit = "#";
    private final Pattern jsonFlatRegexPattern = Pattern.compile("#(.*?)#");
    private final String jsonFlatPattern;

    public JsonFlatExtractor(String pattern, ExtractConfig subExtractConfig) {
        super(pattern, subExtractConfig);
        if ((pattern.length() - pattern.replace(patternSplit, "").length()) % 2 != 0) {
            throw new RuntimeException(String.format("配置的JSON_FLAT: %s 存在错误，请检查配置！", pattern));
        }
        this.jsonFlatPattern = pattern;
    }

    @Override
    public String extract(String input) {
        final Object parsed = JSON.parse(input);
        if (parsed instanceof JSONArray) {
            JSONArray list = (JSONArray) parsed;
            List<String> returnArray = list.stream().map(this::formatPattern).collect(Collectors.toList());
            return JSONObject.toJSONString(returnArray);
        }else if (parsed instanceof JSONObject) {
            return formatPattern(parsed);
        }
        return "";
    }

    public String formatPattern(Object root) {
        StringBuffer resultBuffer = new StringBuffer();
        Matcher matcher = jsonFlatRegexPattern.matcher(jsonFlatPattern);
        while (matcher.find()) {
            String path = matcher.group(1);
            matcher.appendReplacement(resultBuffer, String.valueOf(extractJsonPath(root, path)));
        }
        matcher.appendTail(resultBuffer);
        return resultBuffer.toString();
    }

    public Object extractJsonPath(Object root, String jsonPath) {
        Object jsonExtract = JSONPath.eval(root, jsonPath);
        return null == jsonExtract ? "" : jsonExtract;
    }

}
